package com.ciei.dpagm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ciei.dpagm.common.enums.CircuitGenerationModuleChipColumnEnum;
import com.ciei.dpagm.common.service.BaseService;
import com.ciei.dpagm.entity.Chip;
import com.ciei.dpagm.entity.CircuitGenerationModuleChip;
import com.ciei.dpagm.mapper.CircuitGenerationModuleChipMapper;
import com.ciei.dpagm.util.DateUtil;
import com.ciei.dpagm.util.ExcelUtils;
import com.ciei.dpagm.util.FileUtils;
import com.ciei.dpagm.util.JsonUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CircuitGenerationModuleChipService extends BaseService<CircuitGenerationModuleChipMapper, CircuitGenerationModuleChip> {


    @Autowired
    @Lazy//循环依赖
    private ChipService chipService;

    private static final String EXCEL_FILENAME = "芯片名称统计表.xlsx";

    /**
     * 处理芯片模块映射信息
     *
     * @param mappingArray 映射信息
     * @param chipId       芯片id
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean processMappingArray(JSONArray mappingArray, Integer chipId) {
        // 查询数据库中已存在的映射信息
        List<CircuitGenerationModuleChip> existMappingList = chipId == null ? new ArrayList<>() : findByProperty(CircuitGenerationModuleChip::getChipId, chipId);
        // 将传入的映射信息转换为List
        List<CircuitGenerationModuleChip> mappingList = mappingArray.toJavaList(CircuitGenerationModuleChip.class);
        List<Integer> deleteMappingIdList = new ArrayList<>();
        List<Integer> existIdList = existMappingList.stream().map(CircuitGenerationModuleChip::getId).collect(Collectors.toList());
        // 找到需要添加的映射信息
        List<CircuitGenerationModuleChip> addMappingList = new ArrayList<>();
        List<CircuitGenerationModuleChip> updateMappingList = new ArrayList<>();
        for (CircuitGenerationModuleChip circuitGenerationModuleChip : mappingList) {
            if (existIdList.contains(circuitGenerationModuleChip.getId())) {
                updateMappingList.add(circuitGenerationModuleChip);
            } else {
                circuitGenerationModuleChip.setChipId(chipId);
                addMappingList.add(circuitGenerationModuleChip);
            }
        }
        List<Integer> updateIdList = updateMappingList.stream().map(CircuitGenerationModuleChip::getId).collect(Collectors.toList());
        for (Integer id : existIdList) {
            if (!updateIdList.contains(id)) {
                deleteMappingIdList.add(id);
            }
        }
        // 删除映射信息
        if (!deleteMappingIdList.isEmpty()) {
            removeByIds(deleteMappingIdList);
        }

        // 添加映射信息
        if (!addMappingList.isEmpty()) {
            saveBatch(addMappingList);
        }

        // 更新映射信息
        if (!updateMappingList.isEmpty()) {
            updateBatchById(updateMappingList);
        }

        return true;
    }


    /**
     * 导出芯片模块目标到Excel
     */
    public void exportChipModuleTargetToExcel(HttpServletResponse response) {
        // 联表查询
        LambdaQueryWrapper<CircuitGenerationModuleChip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(CircuitGenerationModuleChip::getChipId);
        List<CircuitGenerationModuleChip> circuitModuleChipsList = list(queryWrapper);
        List<Integer> chipIdList = circuitModuleChipsList.stream().map(CircuitGenerationModuleChip::getChipId).collect(Collectors.toList());
        Map<Integer, Chip> chipIdMap = chipService.findListByIds(chipIdList).stream().collect(Collectors.toMap(Chip::getChipId, chip -> chip));
        JSONArray dataList = new JSONArray();
        for (CircuitGenerationModuleChip circuitModuleChips : circuitModuleChipsList) {
            JSONObject data = new JSONObject();
            data.fluentPut(CircuitGenerationModuleChipColumnEnum.CIRCUIT_MODEL.getDatabaseColumn(), circuitModuleChips.getModel());
            String chipModel = chipIdMap.get(circuitModuleChips.getChipId()) != null ? chipIdMap.get(circuitModuleChips.getChipId()).getModel() : "该芯片名称信息数据有误";
            data.fluentPut(CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getDatabaseColumn(), chipModel);
            dataList.add(data);
        }
        try {
            Map<String, String> headMap = new HashMap<>();
            headMap.put(CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getDatabaseColumn(), CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getExcelColumn());
            headMap.put(CircuitGenerationModuleChipColumnEnum.CIRCUIT_MODEL.getDatabaseColumn(), CircuitGenerationModuleChipColumnEnum.CIRCUIT_MODEL.getExcelColumn());
            // 构建输出流
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(EXCEL_FILENAME.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            OutputStream outputStream = response.getOutputStream();
            // 导出Excel
            ExcelUtils.exportExcelX("芯片名称统计表", headMap, dataList, null, 17, outputStream);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 增量导入芯片模块目标
     *
     * @param request 请求
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject importChipModuleTargetFromExcelIncrement(HttpServletRequest request) {
        return importChipModuleTargetFromExcel(request, true);
    }

    /**
     * 全量导入芯片模块目标
     *
     * @param request 请求
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject importChipModuleTargetFromExcelAll(HttpServletRequest request) {
        return importChipModuleTargetFromExcel(request, false);
    }

    /**
     * 导入芯片模块目标到数据库
     *
     * @param request       请求
     * @param isIncremental 是否增量导入
     */
    @Transactional(rollbackFor = Exception.class)
    public JSONObject importChipModuleTargetFromExcel(HttpServletRequest request, boolean isIncremental) {
        MultipartFile file = FileUtils.getMultipartFileFromRequest(request);
        try {
            List<String> failChipModelList = new ArrayList<>();
            // 调用Excel导入方法
            JSONObject importResult = ExcelUtils.readExcel(file, 0, 1);
            // 处理导入结果
            if (importResult.getBoolean("success")) {
                JSONArray dataArray = importResult.getJSONArray("data");
                List<Row> rowList = dataArray.toJavaList(Row.class);
                Iterator<Row> iterator = rowList.iterator();
                List<List<String>> dataList = new ArrayList<>();
                while (iterator.hasNext()) {
                    Row row = iterator.next();
                    List<String> rowData = new ArrayList<>();
                    for (int i = 0; i < row.getLastCellNum(); i++) {
                        Cell cell = row.getCell(i);
                        if (cell != null) {
                            rowData.add(ExcelUtils.getCellValue(cell, DateUtil.FORMAT_SHORT_SDF));
                        } else {
                            rowData.add("");
                        }
                    }
                    dataList.add(rowData);
                }
                // 获取芯片型号列表
                List<String> chipModelList = dataList.stream().map(data -> data.get(CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getIndex())).collect(Collectors.toList());
                // 构造查询条件
                LambdaQueryWrapper<Chip> chipLambdaQueryWrapper = new LambdaQueryWrapper<>();
                chipLambdaQueryWrapper.in(Chip::getModel, chipModelList);
                // 获取芯片型号和芯片id的映射关系
                Map<String, Integer> chipModelMap =
                        // 正则判断芯片型号是否为空,不为空则查询数据库,为空则返回空map
                        CollectionUtils.isNotEmpty(chipModelList) ?
                                chipService.list(chipLambdaQueryWrapper).stream().collect(Collectors.toMap(Chip::getModel, Chip::getChipId)) : new HashMap<>();
                // 构造芯片模块目标列表
                List<CircuitGenerationModuleChip> circuitGenerationModuleChipList = new ArrayList<>();
                for (List<String> data : dataList) {
                    CircuitGenerationModuleChip circuitGenerationModuleChip = new CircuitGenerationModuleChip();
                    Integer chipId = chipModelMap.get(data.get(CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getIndex()));
                    if (chipId == null) {
                        failChipModelList.add(data.get(CircuitGenerationModuleChipColumnEnum.CHIP_MODEL.getIndex()));
                        continue;
                    }
                    circuitGenerationModuleChip.setChipId(chipId);
                    circuitGenerationModuleChip.setModel(data.get(CircuitGenerationModuleChipColumnEnum.CIRCUIT_MODEL.getIndex()));
                    circuitGenerationModuleChipList.add(circuitGenerationModuleChip);
                }

                // 找出数据库中已存在的数据
                List<CircuitGenerationModuleChip> existList = list();
                if (isIncremental) {
                    // 增量导入，不删除数据
                    circuitGenerationModuleChipList.removeAll(existList);
                } else {
                    // 全量导入，删除不存在的数据
                    List<CircuitGenerationModuleChip> deleteList = new ArrayList<>(existList);
                    deleteList.removeAll(circuitGenerationModuleChipList);

                    // 删除数据
                    if (!deleteList.isEmpty()) {
                        List<Integer> idList = deleteList.stream().map(CircuitGenerationModuleChip::getId).collect(Collectors.toList());
                        removeByIds(idList);
                    }

                    // 从插入数据中删除已存在的数据
                    if (!existList.isEmpty()) {
                        circuitGenerationModuleChipList.removeAll(existList);
                    }
                }

                //执行批量插入
                if (!circuitGenerationModuleChipList.isEmpty()) {
                    saveBatch(circuitGenerationModuleChipList);
                }

                // 返回成功结果
                if (failChipModelList.isEmpty()) {
                    return JsonUtil.getSuccess("导入成功");
                } else {
                    return JsonUtil.getSuccess("部分导入成功，芯片型号为" + String.join(",", failChipModelList) + "的芯片不存在,请检查芯片型号是否正确");
                }
            }
            // 返回失败结果
            return JsonUtil.getFail("导入失败，" + importResult.getString("message"));
        } catch (Exception e) {
            // 处理异常
            log.error(e.getMessage(), e);
            // 返回失败结果
            return JsonUtil.getFail("导入失败，" + e.getMessage());
        }
    }

}
